// 1. 先写一个构造函数
function Vue(options) {
  this.$data = this._data = options.data

  // 1. 实现数据的劫持 也就是说让对象的每个属性都添加一个get与set
  observe(this.$data)

  // 2. 实现数据的代理
  Object.keys(this.$data).forEach(key => {
    this.proxy(key)
  })
}
Vue.prototype = {
  proxy: function (key) {
    // 构造函数原型对象中的方法中的this指的就是构造函数创建的实例对象
    Object.defineProperty(this, key, {
      get() {
        return this.$data[key]
      },
      set(val) {
        this.$data[key] = val
      }
    })
  }
}

function observe(obj) {
  if (!obj || typeof obj !== 'object') return
  // return是用于函数当中，表示返回相应的数据，然后退出当前函数
  // return 后面的代码不再执行

  // data: { msg: 'hello', age: 20 }
  // 获取传递过来的obj中的所有的属性
  // const arr = Object.keys(obj) // [ 'name', 'age', 'address' ]
  // arr.forEach(key => {
  Object.keys(obj).forEach(key => {
    // 先获取当前属性原来的值
    let originValue = obj[key]
    // 如果当前的属性值又是一个对象，需要对这个对象中的属性也要做劫持处理
    observe(originValue)

    Object.defineProperty(obj, key, {
      get() {
        return originValue
      },
      set(value) {
        originValue = value
      }
    })
  })
}

// Object.keys()
// const obj = {
//   name: 'jack',
//   age: 20,
//   address:'深圳市'
// }

// const arr = Object.keys(obj)
// console.log(arr) // [ 'name', 'age', 'address' ]
